#!/usr/bin/perl

#
# Richard Sugg (richardsugg on Library Thing)
# Date 2008-09-05
#

use strict;
#
# This is the name of the directory that will be
# created to store all the data
#
my $DEST_DIR = "LibraryThing";

# 
# The format of the filenames will be a two digit
# number plus the beginning index, a dash, and
# the ending index.  These indexes will be limited
# to the number of characters defined here
#
# For example, when sorting by publishers, and the
# first publisher is "Crossway" and the last 
# publisher is "Zondervan", then the filename will
# be "02 Cross - Zonde"
my $FILE_INDEX_CHARS = 5;

#######################################################
#
# You really won't need to change anything below
# this note
#
#######################################################

#
# These correspond to the column numbers in the
# exported data file.  You really don't want to
# change these unless the columns change.
#
my $TITLE     = 1;
my $AUTHOR    = 2;
my $PUBLISHER = 5;
my $TAGS	  = 21;

#
# Do not change this.  Note files on iPods are 
# limited to 4096 Kb
#
my $MAX_FILE_SIZE = 4096;

my @all_data			= ();
my @sorted_by_author    = ();
my @sorted_by_publisher = ();
my @sorted_by_title     = ();

my $infile = $ARGV[0];

&initialize($infile, \@all_data);

print $#sorted_by_author . " books sorted by author\n";
&convert_to_ipod('By Author',		@sorted_by_author);
&convert_to_ipod('By Publisher',	@sorted_by_publisher);
&convert_to_ipod('By Title',		@sorted_by_title);

sub initialize {
	my ($infile, $all_data) = @_;
	open(I, "$infile") or die "Usage:  $0 <data_file>\nCan't open '$infile' for writing:  $!\n";
	my @all_data = @{$all_data};
	print "Initializing with '$infile'...";
	my $headers		= <I>;
	my @all_books	= <I>;

	mkdir($DEST_DIR) unless (-d $DEST_DIR);
	my @temp_by_title = ();
	my @temp_by_author = ();
	my @temp_by_publisher = ();
	my $lineNumber = 1;
	foreach my $line (@all_books) {
		#printf "%03d\n", $lineNumber++;
		chomp $line;
		my (@info) = split(/\t/, $line);
		my $t = $info[$TITLE];
		my $a = $info[$AUTHOR];
		my $p = $info[$PUBLISHER];
		my $f = "unknown format";
		if($line =~ /format=(\w+)/) {
			$f = $1;
		} 

		$t =~ s/^"//;
		$t =~ s/"$//;

		$a =~ s/^"//;
		$a =~ s/"$//;

		$p =~ s/^"//;
		$p =~ s/"$//;
		$p =~ s/^(.+) (\(\d+\)),.+$/\1 \2/;

		$t = "No Title" if($t =~ /^\s*$/);
		$a = "Unknown" if($a =~ /^\s*$/);
		$p = "Unknown" if($p =~ /^\s*$/);

		push(@temp_by_author,    "$a\t$t\t$a\t$p\t$f");
		my $t2 = $t;
		if($t2 =~ /^The /) {
			$t2 =~ s/^The //;
			$t2 .= ", The";
		}
		
		if($t2 =~ /^(An?) /) {
			my $a = $1;
			$t2 =~ s/^An? //;
			$t .= ", $a";
		}
		push(@temp_by_title,     "$t2\t$t2\t$a\t$p\t$f");
		push(@temp_by_publisher, "$p\t$t\t$a\t$p\t$f");
	}
	@sorted_by_author    = sort @temp_by_author;
	@sorted_by_title     = sort @temp_by_title;
	@sorted_by_publisher = sort @temp_by_publisher;
	print $#all_books . " books to go through\n";
}

sub convert_to_ipod {
	my $subdir = shift;
	my @data = @_;
	print $#data . " books to convert\n";
	mkdir ("$DEST_DIR/$subdir") unless (-d "$DEST_DIR/$subdir");
	my $file_contents = '';
	my $note_count    = 0;
	my $start_with = '';
	my $end_with = '';
	my $last_title = '';
	my $last_author = '';
	my $last_publisher = '';

	#
	# Setup the initial file index
	#
	my ($key, $t, $a, $p, $f) = split(/\t/, $data[0]);
	print $data[0] . "\n";
	print "\n-------------\n$t\n$a\n$p\n--------------\n";
	if($subdir eq "By Author") {
		$start_with = substr($a, 0, $FILE_INDEX_CHARS);
		$start_with =~ s/,.*$//;
	} elsif ($subdir eq "By Title") {
		$start_with = substr($t, 0, $FILE_INDEX_CHARS);
		$start_with =~ s/,.*$//;
	} elsif ($subdir eq "By Publisher") {
		$start_with = substr($p, 0, $FILE_INDEX_CHARS);
		$start_with =~ s/,.*$//;
	}

	foreach my $line (@data) {
		my ($key, $t, $a, $p, $f) = split(/\t/, $line);
		my $newdata =<<EOF;
$t
$a
$p
$f
--------------------------
EOF

		#
		# If the file's contents is full, write it out
		#
		if(length($file_contents) + length($newdata) > $MAX_FILE_SIZE) {
			if($subdir eq "By Author") {
				$end_with = substr($last_author, 0, $FILE_INDEX_CHARS);
			} elsif ($subdir eq "By Title") {
				$end_with = substr($last_title, 0, $FILE_INDEX_CHARS);
			} elsif ($subdir eq "By Publisher") {
				$end_with = substr($last_publisher, 0, $FILE_INDEX_CHARS);
			}
			$end_with =~ s/,.*$//;
			my $filename = "$DEST_DIR/$subdir/" . 
							sprintf("%03d", $note_count++) . 
							" $start_with - $end_with";
			print "Writing data to $filename\n";
			open(O, ">$filename") or die "Can't open $filename for writing:  $!\n";
			print O $file_contents;
			close O;
			$file_contents = $newdata;

			# reset the file's index
			if($subdir eq "By Author") {
				$start_with = substr($a, 0, $FILE_INDEX_CHARS);
				$start_with =~ s/,.*$//;
			} elsif ($subdir eq "By Title") {
				$start_with = substr($t, 0, $FILE_INDEX_CHARS);
				$start_with =~ s/,.*$//;
			} elsif ($subdir eq "By Publisher") {
				$start_with = substr($p, 0, $FILE_INDEX_CHARS);
				$start_with =~ s/,.*$//;
			}
		} else {
			$file_contents .= $newdata;
		}

		$last_title = $t;
		$last_author = $a;
		$last_publisher = $p;
	}
}

